home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / dflat_r_.arc / WINDOW.C < prev   
Text File  |  1991-10-02  |  18KB  |  586 lines

  1. /* ---------- window.c ------------- */
  2.  
  3. #include <stdio.h>
  4. #include <conio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <dos.h>
  8. #include "dflat.h"
  9.  
  10. WINDOW inFocus = NULLWND;
  11.  
  12. int foreground, background;   /* current video colors */
  13.  
  14. static void TopLine(WINDOW, int, RECT);
  15.  
  16. /* --------- create a window ------------ */
  17. WINDOW CreateWindow(
  18.     CLASS class,              /* class of this window       */
  19.     char *ttl,                /* title or NULL              */
  20.     int left, int top,        /* upper left coordinates     */
  21.     int height, int width,    /* dimensions                 */
  22.     void *extension,          /* pointer to additional data */
  23.     WINDOW parent,            /* parent of this window      */
  24.     int (*wndproc)(struct window *,enum messages,PARAM,PARAM),
  25.     int attrib)               /* window attribute           */
  26. {
  27.     WINDOW wnd = calloc(1, sizeof(struct window));
  28.     get_videomode();
  29.     if (wnd != NULLWND)    {
  30.         int base;
  31.         /* ----- height, width = -1: fill the screen ------- */
  32.         if (height == -1)
  33.             height = SCREENHEIGHT;
  34.         if (width == -1)
  35.             width = SCREENWIDTH;
  36.         /* ----- coordinates -1, -1 = center the window ---- */
  37.         if (left == -1)
  38.             wnd->rc.lf = (SCREENWIDTH-width)/2;
  39.         else
  40.             wnd->rc.lf = left;
  41.         if (top == -1)
  42.             wnd->rc.tp = (SCREENHEIGHT-height)/2;
  43.         else
  44.             wnd->rc.tp = top;
  45.         wnd->attrib = attrib;
  46.         if (ttl != NULL)
  47.             AddAttribute(wnd, HASTITLEBAR);
  48.         if (wndproc == NULL)
  49.             wnd->wndproc = classdefs[class].wndproc;
  50.         else
  51.             wnd->wndproc = wndproc;
  52.         /* ---- derive attributes of base classes ---- */
  53.         base = class;
  54.         while (base != -1)    {
  55.             AddAttribute(wnd, classdefs[base].attrib);
  56.             base = classdefs[base].base;
  57.         }
  58.         if (parent && !TestAttribute(wnd, NOCLIP))    {
  59.             /* -- keep upper left within borders of parent - */
  60.             wnd->rc.lf = max(wnd->rc.lf,GetClientLeft(parent));
  61.             wnd->rc.tp = max(wnd->rc.tp,GetClientTop(parent));
  62.         }
  63.         wnd->class = class;
  64.         wnd->extension = extension;
  65.         wnd->rc.rt = GetLeft(wnd)+width-1;
  66.         wnd->rc.bt = GetTop(wnd)+height-1;
  67.         wnd->ht = height;
  68.         wnd->wd = width;
  69.         if (ttl != NULL)
  70.             InsertTitle(wnd, ttl);
  71.         wnd->nextfocus = wnd->prevfocus = wnd->dFocus = NULLWND;
  72.         wnd->parent = parent;
  73.         wnd->condition = ISRESTORED;
  74.         wnd->RestoredRC = wnd->rc;
  75.         wnd->PrevKeyboard = wnd->PrevMouse = NULL;
  76.         SendMessage(wnd, CREATE_WINDOW, 0, 0);
  77.         InitWindowColors(wnd);
  78.         if (isVisible(wnd))
  79.             SendMessage(wnd, SHOW_WINDOW, 0, 0);
  80.     }
  81.     return wnd;
  82. }
  83.  
  84. /* -------- add a title to a window --------- */
  85. void AddTitle(WINDOW wnd, char *ttl)
  86. {
  87.     InsertTitle(wnd, ttl);
  88.     SendMessage(wnd, BORDER, 0, 0);
  89. }
  90.  
  91. /* ----- insert a title into a window ---------- */
  92. void InsertTitle(WINDOW wnd, char *ttl)
  93. {
  94.     if ((wnd->title=realloc(wnd->title,strlen(ttl)+1)) != NULL)
  95.         strcpy(wnd->title, ttl);
  96. }
  97.  
  98. int CharInView(WINDOW wnd, int x, int y)
  99. {
  100.     int x1 = GetLeft(wnd)+x;
  101.     int y1 = GetTop(wnd)+y;
  102.  
  103.     if (isVisible(wnd))    {
  104.         if (!TestAttribute(wnd, NOCLIP))    {
  105.             WINDOW wnd1 = GetParent(wnd);
  106.             while (wnd1 != NULLWND)    {
  107.                 /* --- clip character to parent's borders -- */
  108.                 if (x1 < GetClientLeft(wnd1)   ||
  109.                     x1 > GetClientRight(wnd1)  ||
  110.                     y1 > GetClientBottom(wnd1) ||
  111.                     y1 < GetClientTop(wnd1))
  112.                         return FALSE;
  113.                 wnd1 = GetParent(wnd1);
  114.             }
  115.         }
  116.     }
  117.     return (x1 < SCREENWIDTH && y1 < SCREENHEIGHT);
  118. }
  119.  
  120. /* ------- write a character to a window area at x,y ------- */
  121. void PutWindowChar(WINDOW wnd, int x, int y, int c)
  122. {
  123.     if (CharInView(wnd, x, y))
  124.         wputch(wnd, c, x, y);
  125. }
  126.  
  127. static unsigned char line[300];
  128.  
  129. #ifdef INCLUDE_SYSTEM_MENUS
  130.  
  131. /* ----- clip line if it extends below the bottom of the
  132.              parent window ------ */
  133. static int clipbottom(WINDOW wnd, int y)
  134. {
  135.     if (!TestAttribute(wnd, NOCLIP))    {
  136.         WINDOW wnd1 = GetParent(wnd);
  137.         while (wnd1 != NULLWND)    {
  138.             if (GetClientTop(wnd)+y > GetClientBottom(wnd1)+1)
  139.                 return TRUE;
  140.             wnd1 = GetParent(wnd1);
  141.         }
  142.     }
  143.     return GetTop(wnd)+y > SCREENHEIGHT;
  144. }
  145.  
  146. /* ------ clip the portion of a line that extends past the
  147.                      right margin of the parent window ----- */
  148. void clipline(WINDOW wnd, int x, char *ln)
  149. {
  150.     WINDOW pwnd = GetParent(wnd);
  151.     int x1 = strlen(ln);
  152.     int i = 0;
  153.  
  154.     if (!TestAttribute(wnd, NOCLIP))    {
  155.         while (pwnd != NULLWND)    {
  156.             x1 = GetClientRight(pwnd) - GetLeft(wnd) - x + 1;
  157.             pwnd = GetParent(pwnd);
  158.         }
  159.     }
  160.     else if (GetLeft(wnd) + x > SCREENWIDTH)
  161.         x1 = SCREENWIDTH-GetLeft(wnd) - x;
  162.     /* --- adjust the clipping offset for color controls --- */
  163.     if (x1 < 0)
  164.         x1 = 0;
  165.     while (i < x1)    {
  166.         if ((unsigned char) ln[i] == CHANGECOLOR)
  167.             i += 3, x1 += 3;
  168.         else if ((unsigned char) ln[i] == RESETCOLOR)
  169.             i++, x1++;
  170.         else 
  171.             i++;
  172.     }
  173.     ln[x1] = '\0';
  174. }
  175. #else
  176. #define clipbottom(w,y) FALSE
  177. #endif
  178.  
  179. /* ------ write a line to video window client area ------ */
  180. void writeline(WINDOW wnd, char *str, int x, int y, int pad)
  181. {
  182.     if (!clipbottom(wnd, y))
  183.     {
  184.         char *cp;
  185.         int len;
  186.         int dif;
  187.         char *wline = malloc(200);
  188.  
  189.         if (wline != NULL)    {
  190.             memset(wline, 0, 200);
  191.             len = LineLength(str);
  192.             dif = strlen(str) - len;
  193.             strncpy(wline, str, ClientWidth(wnd) + dif);
  194.             if (pad)    {
  195.                 cp = wline+strlen(wline);
  196.                 while (len++ < ClientWidth(wnd)-x)
  197.                     *cp++ = ' ';
  198.             }
  199.             clipline(wnd, x, wline);
  200.             wputs(wnd, wline, x, y);
  201.             free(wline);
  202.         }
  203.     }
  204. }
  205.  
  206. RECT AdjustRectangle(WINDOW wnd, RECT rc)
  207. {
  208.     /* -------- adjust the rectangle ------- */
  209.     if (TestAttribute(wnd, HASBORDER))    {
  210.         if (RectLeft(rc) == 0)
  211.             --rc.rt;
  212.         else if (RectLeft(rc) < RectRight(rc) &&
  213.                 RectLeft(rc) < WindowWidth(wnd)+1)
  214.             --rc.lf;
  215.     }
  216.     if (TestAttribute(wnd, HASBORDER | HASTITLEBAR))    {
  217.         if (RectTop(rc) == 0)
  218.             --rc.bt;
  219.         else if (RectTop(rc) < RectBottom(rc) &&
  220.                 RectTop(rc) < WindowHeight(wnd)+1)
  221.             --rc.tp;
  222.     }
  223.     RectRight(rc) = max(RectLeft(rc),
  224.                         min(RectRight(rc),WindowWidth(wnd)));
  225.     RectBottom(rc) = max(RectTop(rc),
  226.                         min(RectBottom(rc),WindowHeight(wnd)));
  227.     return rc;
  228. }
  229.  
  230. /* -------- display a window's title --------- */
  231. void DisplayTitle(WINDOW wnd, RECT *rcc)
  232. {
  233.     if (GetTitle(wnd) != NULL)    {
  234.         int tlen = min(strlen(GetTitle(wnd)), WindowWidth(wnd)-2);
  235.         int tend = WindowWidth(wnd)-3-BorderAdj(wnd);
  236.         RECT rc;
  237.  
  238.         if (rcc == NULL)
  239.             rc = RelativeWindowRect(wnd, WindowRect(wnd));
  240.         else
  241.             rc = *rcc;
  242.         rc = AdjustRectangle(wnd, rc);
  243.  
  244.         if (SendMessage(wnd, TITLE, (PARAM) rcc, 0))    {
  245.             if (wnd == inFocus)    {
  246.                 foreground = cfg.clr[TITLEBAR] [HILITE_COLOR] [FG];
  247.                 background = cfg.clr[TITLEBAR] [HILITE_COLOR] [BG];
  248.             }
  249.             else    {
  250.                 foreground = cfg.clr[TITLEBAR] [STD_COLOR] [FG];
  251.                 background = cfg.clr[TITLEBAR] [STD_COLOR] [BG];
  252.             }
  253.             memset(line,' ',WindowWidth(wnd));
  254.             if (wnd->condition != ISMINIMIZED)
  255.                 strncpy(line + ((WindowWidth(wnd)-2 - tlen) / 2),
  256.                     wnd->title, tlen);
  257.             if (TestAttribute(wnd, CONTROLBOX))
  258.                 line[2-BorderAdj(wnd)] = CONTROLBOXCHAR;
  259. #ifdef INCLUDE_SYSTEM_MENUS
  260.             if (TestAttribute(wnd, MINMAXBOX))    {
  261.                 switch (wnd->condition)    {
  262.                     case ISRESTORED:
  263.                         line[tend+1] = MAXPOINTER;
  264.                         line[tend]   = MINPOINTER;
  265.                         break;
  266.                     case ISMINIMIZED:
  267.                         line[tend+1] = MAXPOINTER;
  268.                         break;
  269.                     case ISMAXIMIZED:
  270.                         line[tend]   = MINPOINTER;
  271.                         line[tend+1] = RESTOREPOINTER;
  272.                         break;
  273.                     default:
  274.                         break;
  275.                 }
  276.             }
  277. #endif
  278.             line[RectRight(rc)+1] = line[tend+3] = '\0';
  279.             writeline(wnd, line+RectLeft(rc),
  280.                            RectLeft(rc)+BorderAdj(wnd),
  281.                            0,
  282.                            FALSE);
  283.         }
  284.     }
  285. }
  286.  
  287. #ifdef INCLUDE_SHADOWS
  288. /* --- display right border shadow character of a window --- */
  289. static void near shadow_char(WINDOW wnd, int y)
  290. {
  291.     int fg = foreground;
  292.     int bg = background;
  293.     int x = WindowWidth(wnd);
  294.     int c = videochar(GetLeft(wnd)+x, GetTop(wnd)+y);
  295.  
  296.     if (TestAttribute(wnd, SHADOW) == 0)
  297.         return;
  298.     foreground = DARKGRAY;
  299.     background = BLACK;
  300.     PutWindowChar(wnd, x, y, c);
  301.     foreground = fg;
  302.     background = bg;
  303. }
  304.  
  305. /* --- display the bottom border shadow line for a window -- */
  306. static void near shadowline(WINDOW wnd, RECT rc)
  307. {
  308.     int i;
  309.     int y = GetBottom(wnd)+1;
  310.  
  311.     if ((TestAttribute(wnd, SHADOW)) == 0)
  312.         return;
  313.     if (!clipbottom(wnd, WindowHeight(wnd)))    {
  314.         int fg = foreground;
  315.         int bg = background;
  316.         for (i = 0; i < WindowWidth(wnd)+1; i++)
  317.             line[i] = videochar(GetLeft(wnd)+i, y);
  318.         line[i] = '\0';
  319.         foreground = DARKGRAY;
  320.         background = BLACK;
  321.         clipline(wnd, 0, line);
  322.         line[RectRight(rc)+1] = '\0';
  323.         if (RectLeft(rc) == 0)
  324.             rc.lf++;
  325.         wputs(wnd, line+RectLeft(rc), RectLeft(rc),
  326.             WindowHeight(wnd));
  327.         foreground = fg;
  328.         background = bg;
  329.     }
  330. }
  331. #endif
  332.  
  333. /* ------- display a window's border ----- */
  334. void RepaintBorder(WINDOW wnd, RECT *rcc)
  335. {
  336.     int y;
  337.     unsigned int lin, side, ne, nw, se, sw;
  338.     RECT rc, clrc;
  339.  
  340.     if (!TestAttribute(wnd, HASBORDER))
  341.         return;
  342.     if (rcc == NULL)    {
  343.         rc = RelativeWindowRect(wnd, WindowRect(wnd));
  344. #ifdef INCLUDE_SHADOWS
  345.         if (TestAttribute(wnd, SHADOW))    {
  346.             rc.rt++;
  347.             rc.bt++;
  348.         }
  349. #endif
  350.     }
  351.     else
  352.         rc = *rcc;
  353.     clrc = AdjustRectangle(wnd, rc);
  354.  
  355.     if (wnd == inFocus)    {
  356.         lin  = FOCUS_LINE;
  357.         side = FOCUS_SIDE;
  358.         ne   = FOCUS_NE;
  359.         nw   = FOCUS_NW;
  360.         se   = FOCUS_SE;
  361.         sw   = FOCUS_SW;
  362.     }
  363.     else    {
  364.         lin  = LINE;
  365.         side = SIDE;
  366.         ne   = NE;
  367.         nw   = NW;
  368.         se   = SE;
  369.         sw   = SW;
  370.     }
  371.     line[WindowWidth(wnd)] = '\0';
  372.     /* ---------- window title ------------ */
  373.     if (TestAttribute(wnd, HASTITLEBAR))
  374.         if (RectTop(rc) == 0)
  375.             if (RectLeft(rc) < WindowWidth(wnd)-BorderAdj(wnd))
  376.                 DisplayTitle(wnd, &rc);
  377.     foreground = FrameForeground(wnd);
  378.     background = FrameBackground(wnd);
  379.     /* -------- top frame corners --------- */
  380.     if (RectTop(rc) == 0)    {
  381.         if (RectLeft(rc) == 0)
  382.             PutWindowChar(wnd, 0, 0, nw);
  383.         if (RectLeft(rc) < WindowWidth(wnd))    {
  384.             if (RectRight(rc) >= WindowWidth(wnd)-1)
  385.                 PutWindowChar(wnd, WindowWidth(wnd)-1, 0, ne);
  386.             TopLine(wnd, lin, clrc);
  387.         }
  388.     }
  389.  
  390.     /* ----------- window body ------------ */
  391.     for (y = RectTop(rc); y <= RectBottom(rc); y++)    {
  392.         int ch;
  393.         if (y == 0 || y >= WindowHeight(wnd)-1)
  394.             continue;
  395.         if (RectLeft(rc) == 0)
  396.             PutWindowChar(wnd, 0, y, side);
  397.         if (RectLeft(rc) < WindowWidth(wnd) &&
  398.                 RectRight(rc) >= WindowWidth(wnd)-1)    {
  399. #ifdef INCLUDE_SCROLLBARS
  400.             if (TestAttribute(wnd, VSCROLLBAR))
  401.                 ch = (    y == 1 ? UPSCROLLBOX      :
  402.                           y == WindowHeight(wnd)-2  ?
  403.                                 DOWNSCROLLBOX       :
  404.                           y-1 == wnd->VScrollBox    ?
  405.                                 SCROLLBOXCHAR       :
  406.                           SCROLLBARCHAR );
  407.             else
  408. #endif
  409.                 ch = side;
  410.             PutWindowChar(wnd, WindowWidth(wnd)-1, y, ch);
  411.         }
  412. #ifdef INCLUDE_SHADOWS
  413.         if (RectRight(rc) == WindowWidth(wnd))
  414.             shadow_char(wnd, y);
  415. #endif
  416.     }
  417.  
  418.     if (RectTop(rc) <= WindowHeight(wnd)-1 &&
  419.             RectBottom(rc) >= WindowHeight(wnd)-1)    {
  420.         /* -------- bottom frame corners ---------- */
  421.         if (RectLeft(rc) == 0)
  422.             PutWindowChar(wnd, 0, WindowHeight(wnd)-1, sw);
  423.         if (RectLeft(rc) < WindowWidth(wnd) &&
  424.                 RectRight(rc) >= WindowWidth(wnd)-1)
  425.             PutWindowChar(wnd, WindowWidth(wnd)-1,
  426.                 WindowHeight(wnd)-1, se);
  427.  
  428.  
  429.         if (wnd->StatusBar == NULLWND)    {
  430.             /* ----------- bottom line ------------- */
  431.             memset(line,lin,WindowWidth(wnd)-1);
  432. #ifdef INCLUDE_SCROLLBARS
  433.             if (TestAttribute(wnd, HSCROLLBAR))    {
  434.                 line[0] = LEFTSCROLLBOX;
  435.                 line[WindowWidth(wnd)-3] = RIGHTSCROLLBOX;
  436.                 memset(line+1, SCROLLBARCHAR, WindowWidth(wnd)-4);
  437.                 line[wnd->HScrollBox] = SCROLLBOXCHAR;
  438.             }
  439. #endif
  440.             line[WindowWidth(wnd)-2] = line[RectRight(rc)] = '\0';
  441.             if (RectLeft(rc) != RectRight(rc) ||
  442.             (RectLeft(rc) && RectLeft(rc) < WindowWidth(wnd)-1))
  443.                 writeline(wnd,
  444.                     line+(RectLeft(clrc)),
  445.                     RectLeft(clrc)+1,
  446.                     WindowHeight(wnd)-1,
  447.                     FALSE);
  448.         }
  449. #ifdef INCLUDE_SHADOWS
  450.         if (RectRight(rc) == WindowWidth(wnd))
  451.             shadow_char(wnd, WindowHeight(wnd)-1);
  452. #endif
  453.     }
  454. #ifdef INCLUDE_SHADOWS
  455.     if (RectBottom(rc) == WindowHeight(wnd))
  456.         /* ---------- bottom shadow ------------- */
  457.         shadowline(wnd, rc);
  458. #endif
  459. }
  460.  
  461. static void TopLine(WINDOW wnd, int lin, RECT rc)
  462. {
  463.     if (TestAttribute(wnd, HASMENUBAR))
  464.         return;
  465.     if (TestAttribute(wnd, HASTITLEBAR) && GetTitle(wnd))
  466.         return;
  467.     if (RectLeft(rc) == 0)    {
  468.         RectLeft(rc) += BorderAdj(wnd);
  469.         RectRight(rc) += BorderAdj(wnd);
  470.     }
  471.     if (RectRight(rc) < WindowWidth(wnd)-1)
  472.         RectRight(rc)++;
  473.  
  474.     if (RectLeft(rc) < RectRight(rc))    {
  475.         /* ----------- top line ------------- */
  476.         memset(line,lin,WindowWidth(wnd)-1);
  477.         if (TestAttribute(wnd, CONTROLBOX))    {
  478.             strncpy(line+1, "   ", 3);
  479.             *(line+2) = CONTROLBOXCHAR;
  480.         }
  481.         line[RectRight(rc)] = '\0';
  482.         writeline(wnd, line+RectLeft(rc),
  483.             RectLeft(rc), 0, FALSE);
  484.     }
  485. }
  486.  
  487. /* ------ clear the data space of a window -------- */
  488. void ClearWindow(WINDOW wnd, RECT *rcc, int clrchar)
  489. {
  490.     if (isVisible(wnd))    {
  491.         int y;
  492.         RECT rc;
  493.  
  494.         if (rcc == NULL)
  495.             rc = RelativeWindowRect(wnd, WindowRect(wnd));
  496.         else
  497.             rc = *rcc;
  498.  
  499.         if (RectLeft(rc) == 0)
  500.             RectLeft(rc) = BorderAdj(wnd);
  501.         if (RectRight(rc) > WindowWidth(wnd)-1)
  502.             RectRight(rc) = WindowWidth(wnd)-1;
  503.         SetStandardColor(wnd);
  504.         memset(line, clrchar, sizeof line);
  505.         line[RectRight(rc)+1] = '\0';
  506.         for (y = RectTop(rc); y <= RectBottom(rc); y++)    {
  507.             if (y < TopBorderAdj(wnd) ||
  508.                     y > ClientHeight(wnd)+1)
  509.                 continue;
  510.             writeline(wnd,
  511.                 line+(RectLeft(rc)),
  512.                 RectLeft(rc),
  513.                 y,
  514.                 FALSE);
  515.         }
  516.     }
  517. }
  518.  
  519. /* -- adjust a window's rectangle to clip it to its parent - */
  520. static RECT near ClipRect(WINDOW wnd)
  521. {
  522.     RECT rc;
  523.     rc = wnd->rc;
  524. #ifdef INCLUDE_SHADOWS
  525.     if (TestAttribute(wnd, SHADOW))    {
  526.         RectBottom(rc)++;
  527.         RectRight(rc)++;
  528.     }
  529. #endif
  530.     return ClipRectangle(wnd, rc);
  531. }
  532.  
  533. /* -- get the video memory that is to be used by a window -- */
  534. void GetVideoBuffer(WINDOW wnd)
  535. {
  536.     RECT rc;
  537.     int ht;
  538.     int wd;
  539.  
  540.     rc = ClipRect(wnd);
  541.     ht = RectBottom(rc) - RectTop(rc) + 1;
  542.     wd = RectRight(rc) - RectLeft(rc) + 1;
  543.     wnd->videosave = realloc(wnd->videosave, (ht * wd * 2));
  544.     get_videomode();
  545.     if (wnd->videosave != NULL)
  546.         getvideo(rc, wnd->videosave);
  547. }
  548.  
  549. /* --- restore the video memory that was used by a window -- */
  550. void RestoreVideoBuffer(WINDOW wnd)
  551. {
  552.     if (wnd->videosave != NULL)    {
  553.         RECT rc;
  554.         rc = ClipRect(wnd);
  555.         storevideo(rc, wnd->videosave);
  556.         free(wnd->videosave);
  557.         wnd->videosave = NULL;
  558.     }
  559. }
  560.  
  561. /* ------ compute the logical line length of a window ------ */
  562. int LineLength(char *ln)
  563. {
  564.     int len = strlen(ln);
  565.     char *cp = ln;
  566.     while ((cp = strchr(cp, CHANGECOLOR)) != NULL)    {
  567.         cp++;
  568.         len -= 3;
  569.     }
  570.     cp = ln;
  571.     while ((cp = strchr(cp, RESETCOLOR)) != NULL)    {
  572.         cp++;
  573.         --len;
  574.     }
  575.     return len;
  576. }
  577.  
  578. void InitWindowColors(WINDOW wnd)
  579. {
  580.     int fbg,col;
  581.     /* ---------- set the colors ---------- */
  582.     for (fbg = 0; fbg < 2; fbg++)
  583.         for (col = 0; col < 4; col++)
  584.             wnd->WindowColors[col][fbg] = cfg.clr[GetClass(wnd)][col][fbg];
  585. }
  586.